package com.txby.platformCore.component.service;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Switch;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.google.common.collect.Maps;
import com.jck.mybatis.log.TxbyLogger;
import com.jck.mybatis.mapper.MybatisBaseDaoCRUD;
import com.jck.tools.ChkUtil;
import com.jck.tools.GetIp;
import com.jck.tools.HttpToolUtil;
import com.jck.tools.MD5Util;
import com.jck.tools.Times;
import com.jck.tools.component.controller.BaseController;
import com.jck.tools.easyui.ResponseUtils;
import com.jck.tools.exception.BusinessException;
import com.jck.tools.exception.ParameterException;
import com.jck.tools.util.FreeMarkers;
import com.txby.platformCore.component.util.TreeNode;
import com.txby.platformCore.component.util.TreeUtil;
import com.txby.platformCore.data.CommonApiModelMapExt;
import com.txby.platformCore.data.CommonMybaitsDataMapExt;
import com.txby.platformCore.data.EntityData;
import com.txby.platformCore.entity.DctNrsCardCnf;
import com.txby.platformCore.entity.ProductDeviceInit;
import com.txby.platformCore.entity.SickDetailInfo;
import com.txby.platformCore.entity.TxbyBDApiConfig;
import com.txby.platformCore.entity.TxbyBDApiMonition;
import com.txby.platformCore.entity.TxbySysApiUser;
import com.txby.platformCore.entity.VisitorUser;

public class CommonController extends BaseController {
	@Resource(name = "mybatisBaseDaoCRUD")
	public MybatisBaseDaoCRUD mBaseDao;
	@Resource
	public PropertySourceConfig propertySourceConfig;
	@Resource(name = "springEhcacheUtil")
	public SpringEhcacheUtil springEhcacheUtil;
	@Resource
	public GlobalLogAspectInterceptor globalLog;

	public String apiTokenCachName = "apiTokenCache";// 缓存名称
	private HttpServletRequest request;
	private HttpServletResponse response;

	public boolean isHisErr;// 是否his接口异常
	public String  fullClassNamePre="his-";// his Api配置typeFlag 前缀
	public boolean isTokenValid;// 是否token有效
	public static String apiUserId = "";// 用户id
	public String userToken = "";// 当前token
	public Integer reParamType ;// 当前请求类型// 0:web,1:android,2:iphone

	public String clientIP = "";// 当前IP
	public String requestMethod = "";// 当前请求方法
	public  String tempTableName = "";// in查询时超过1000创建的临时表名
	public  boolean isGlobaltempTable=true;//是全局（所有会话）还是本地（当前会话）
	
	public String userAgent="";//用户代理头
	public String errmsg="";//提示信息
	public Integer  errcode=0;//0为正常，其他失败
	public String info;//开发内部提示信息
	public String msg;//提示信息
	public Integer  code;//1为正常，其他失败
	public Integer  expires;//有效期秒
	public String cacheTreeData="cacheTreeData";//
	private static Logger logger = LoggerFactory.getLogger(CommonController.class);
	public String demoDeviceSN="af24b555b64b1e6c";//默认demo 设备数据绑定
	
	public VisitorUser vu=null;
	public SickDetailInfo sdi=null;
	
	@Override
	public String exp(HttpServletRequest request, Exception ex, HttpServletResponse res) {
		res.setCharacterEncoding("UTF-8");
		ex.printStackTrace();
		request.setAttribute("ex", ex);
		res.getStatus();
		if (ex instanceof BusinessException) {
			logger.error(ex.getMessage(), ex);
			return "error/500";
		} else if (ex instanceof ParameterException) {
			logger.error(ex.getMessage(), ex);
			return "error/404";
		} else {
//			return "{\"code\":\"1\",\"info\":\"请求异常\",\"msg\":\"请求异常\"}";
			this.errmsg="系统开小差，稍后重试";
			this.errcode=5000;
		/*	this.info=errmsg;
			this.msg=errmsg;*/
			Map  returnMap=new HashMap(){{
				put("errmsg", errmsg);
				put("errcode", errcode);
				put("code", code);
				put("info", info);
				put("msg", msg);
				
			}};
			return ResponseUtils.toJSONString(returnMap);
			 
		}
	}

	/**
	 * 上传单文件（文件name参数名file）,按日期hh:mmss:sss命名 code 4017: 上传出现异常 4018:
	 * 上传文件大小受限制（不能超过2M） 4019:文件格式受限制（支持gif、png、jpg、bmp）
	 * 
	 * @param request
	 * @param savePath
	 * @return
	 */
	@Override
	public Map fileUpload(HttpServletRequest request, String savePath) {
		Map m = new HashMap();
		m.put(CommonApiModelMapExt.ERRCODE, 4017);
		m.put(CommonApiModelMapExt.CODE, 4017);
		m.put(CommonApiModelMapExt.ERRMSG, "上传出现异常");
		m.put(CommonApiModelMapExt.MSG, "上传出现异常");
		m.put(CommonApiModelMapExt.INFO, "上传出现异常");
		m.put("url", "");
		try {
			Date date = new Date();
			String newName = Times.getDateToStringHHmmssSSS(date);// 自定义文件名字
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			CommonsMultipartFile orginalFile = (CommonsMultipartFile) multipartRequest
					.getFile("tradingCertificatePicFile");// 表单中对应的文件名；
			if (orginalFile != null && !orginalFile.isEmpty()) {
				String fileName = orginalFile.getOriginalFilename();
				String suffix = fileName.substring(fileName.indexOf("."));// 获得后缀名

				long size = orginalFile.getSize();
				/*
				 * if(orginalFile.getSize()>6024*2000){ m.put("code", "4018");
				 * m.put("info","图片上传文件大小受限制（不能超过2M）"); m.put("msg",
				 * "图片不能大于2M"); return m; }
				 */

				if (!suffix.equals(".bmp") && !suffix.equals(".gif") && !suffix.equals(".png")
						&& !suffix.equals(".jpg")) {
					m.put("code", "4019");
					m.put("info", "文件格式受限制（支持gif、png、jpg、bmp）");
					m.put("msg", "上传格式应为gif、png、jpg、bmp");
					m.put(CommonApiModelMapExt.ERRCODE, 4019);
					m.put(CommonApiModelMapExt.CODE, 4019);
					m.put(CommonApiModelMapExt.ERRMSG,"文件格式受限制（支持gif、png、jpg、bmp）");
					m.put(CommonApiModelMapExt.MSG,"文件格式受限制（支持gif、png、jpg、bmp）");
					m.put(CommonApiModelMapExt.INFO, "文件格式受限制（支持gif、png、jpg、bmp）");
					return m;
				}
				fileName = newName + suffix;
				File file = new File(savePath);
				if (!file.exists()) {// 判断文件夹是否存在，不存在就根据上面的路径创建文件夹
					file.mkdirs();
				}
				String realpath = request.getSession().getServletContext().getRealPath(savePath);// 给予存储路径
				File f = new File(realpath + File.separator + fileName);
				String url = savePath + fileName;// 获得相对路径
				FileUtils.copyInputStreamToFile(orginalFile.getInputStream(), f);// 获取文件，并按照路径保存
				
				m.put(CommonApiModelMapExt.ERRCODE, 0);
				m.put(CommonApiModelMapExt.CODE, 1);
				m.put(CommonApiModelMapExt.ERRMSG, "上传成功");
				m.put(CommonApiModelMapExt.MSG, "上传成功");
				m.put(CommonApiModelMapExt.INFO, "上传成功");
				m.put("url", url);
				m.put("date", date);
				return m;
			}

		} catch (Exception e) {
			e.printStackTrace();

			return m;
		}

		return m;
	}

	/**
	 * 根据用户获取token
	 * 
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param userData
	 * @return token,用户id字符+“#”动态码
	 */
	public String getCreateTokenByTxbySysApiUser(TxbySysApiUser userData) {
		String userId = userData.getId() + "_";
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + verifyCode;
		return token;
	}

	/**
	 * 根据用户获取token并放入cache
	 * @param userData
	 * @return
	 */
	public CommonApiModelMapExt getCreateTokenByTxbySysApiUserAndPutCache(TxbySysApiUser userData) {
		String userId = userData.getId();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}
	/**
	 * 根据用户获取token并放入cache
	 * @param userData
	 * @return
	 */
	public CommonApiModelMapExt getDemoCreateTokenByTxbySysApiUserAndPutCache(TxbySysApiUser userData) {
		String demoPrefix="demo:";
		String userId = demoPrefix+userData.getId();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}
	/**
	 * 根据用户获取token并放入cache
	 * @param userData
	 * @return
	 */
	public CommonApiModelMapExt getCreateTokenByVisitorUserAndPutCache(VisitorUser userData) {
		String userId = "vst:"+userData.getId_();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}
	//访客待登录验证
	public CommonApiModelMapExt getCreateTokenByWaitvstAndPutCache(VisitorUser userData) {
		String userId = "waitvst:"+userData.getId();
		String verifyCode = MD5Util.getMD5ofStr(userId + userData.getPassWord() + new Date().getTime(), 2);
		String token = userId + "_" + verifyCode;
		putTokenCache(userId + "_token", token);
		CommonApiModelMapExt m=new CommonApiModelMapExt(0,  "token正常", null, null, null);
		m.put("token", token);
//		long expires=
//				println()println(springEhcacheUtil.getCacheManager().getCache("apiTokenCache"))
//				println()
		long expires=springEhcacheUtil.getCacheManager().getCache("apiTokenCache").getCacheConfiguration().getTimeToIdleSeconds();
		m.put("expires",expires);
		return 	m;
	}

	public CommonApiModelMapExt chekTokenCahceValid(String token, Integer type){
/*		if(true){
			isTokenValid = true;
//		apiUserId = data[0];// 用户id
			userToken = token;// 当前token
			reParamType = type;// 当前请求类型（须）0：web,1:app
			this.springEhcacheUtil.put(apiTokenCachName, apiUserId + "_token", token);
			return new CommonApiModelMapExt(0,"token正常", null, null, null) ;
			
		}*/
		List oldTypeList = Arrays.asList(0, 1,2);// 0:web,1:android,2:iphone
		if (!oldTypeList.contains(type)) {
			isTokenValid = false;
			apiUserId = "";// 用户id
			userToken = "";// 当前token
			reParamType = null;// 当前请求类型// 0:web,1:android,2:iphone
//			return writeReturnJson(SERVER_ERR.CODE_1.getCode(), "验证失败,参数不正确", "验证失败,参数不正确");
			return new CommonApiModelMapExt(4000, "type验证失败,参数类型不正确", null, null, null);
		}else {
			try {
				String[] data = token.split("_");
				if (data.length < 2) {
					isTokenValid = false;
					apiUserId = "";// 用户id
					userToken = "";// 当前token
					reParamType = null;// 当前请求类型（须）0：web,1:app
					return new CommonApiModelMapExt(4001, "token验证失败,格式不正确", null, null, null);
				}else{
					apiUserId = data[0];// 用户id
					String oldtoken = (String) springEhcacheUtil.get(apiTokenCachName, apiUserId + "_token");
					if (ChkUtil.isEmpty(oldtoken)) {
						isTokenValid = false;
						apiUserId = "";// 用户id
						userToken = "";// 当前token
						reParamType = null;// 当前请求类型（须）0：web,1:app
						return new CommonApiModelMapExt(4002, "token验证失效,请重新登录验证", null, null, null);
					}
					
					if (!oldtoken.equals(token)) {
						isTokenValid = false;
						apiUserId = "";// 用户id
						userToken = "";// 当前token
						reParamType = null;// 当前请求类型（须）0：web,1:app
						 return new CommonApiModelMapExt(4003,"token验证失效，用户已在其他设备登录,请重新登录验证", null, null, null) ;
					} else{
						isTokenValid = true;
						apiUserId = data[0];// 用户id
						userToken = token;// 当前token
						reParamType = type;// 当前请求类型（须）0：web,1:app
						this.springEhcacheUtil.put(apiTokenCachName, apiUserId + "_token", token);
						return new CommonApiModelMapExt(0,"token正常", null, null, null) ;
					}
				}
			} catch (Exception e) {
				isTokenValid = false;
				apiUserId = "";// 用户id
				userToken = "";// 当前token
				reParamType = null;// 当前请求类型（须）0：web,1:app
				e.printStackTrace();
				saveLog("传入的token异常，可能格式不正确");
				return new CommonApiModelMapExt(5000,"token正常", null, null, null) ;
			}
			
		}

	}

	public Map tokenNotValid(CommonApiModelMapExt map) throws IOException {
		if (!this.isTokenValid) {
			map.clear();
			map =new CommonApiModelMapExt(1,"token异常", null, null, null) ;
		} else {
			map =  new CommonApiModelMapExt(1,"token正常", null, null, null);
		}
		return map;
	}

 

	/**
	 * 存放token缓存，默认token,存活1小时，间隔1小时内有效
	 * 
	 * @param key
	 * @param value
	 */
	/*
	 * public void putTokenCache(String key,String value){
	 * this.springEhcacheUtil.put(apiTokenCachName, key, value); }
	 */
	public void putTokenCache(String key, String value) {
		this.springEhcacheUtil.put(apiTokenCachName, key, value);
	}

	/**
	 * 用户手动日志保存(格式)
	 * 
	 * @param message
	 */
	public void saveLog(String message) {
		if (isTokenValid) {
			TxbyLogger.getLogger(TxbyLogger.class).log(TxbyLogger.getTxbyLoggerLevel(), "触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + ",用户：" + apiUserId + "" + "，信息说明：" + message + "");
			/*logger.warn("触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + ",用户：" + apiUserId + "" + "，信息说明：" + message + "");*/
		} else {
		/*	logger.warn("触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + "，信息说明：" + message + "");*/
			
			TxbyLogger.getLogger(TxbyLogger.class).log(TxbyLogger.getTxbyLoggerLevel(), "触发时间：" + Times.getTimes() + "，IP:" + clientIP + ",请求参数类型" + reParamType + ",请求方法类型"
					+ requestMethod + "，信息说明：" + message + "");
		}
	}

	/**
	 * 先执行此处
	 * 
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param token
	 * @param type
	 * @param request
	 */
	@ModelAttribute
	public void initModelAttribute(HttpServletRequest request, HttpServletResponse response) {
		this.request = request;
		this.response = response;
		this.requestMethod = request.getMethod().toUpperCase();
		try {
			this.clientIP = GetIp.getIpAddr(request);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	/**
	 * @Description:sql in条件查询拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitInSql(String[] sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += "'" + str + "',";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: sql in条件查询拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitInSql(Set<String> sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += "'" + str + "',";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: 保存数据表中，外键id的“，”分割的拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitNewString(String[] sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += str + ",";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}

	/**
	 * @Description: 保存数据表中，外键id的“，”分割的拆分
	 * @param sqlId
	 * @return
	 */
	public static String getSplitNewString(Set<String> sqlId) {
		String sql = "";
		for (String str : sqlId) {
			sql += str + ",";
		}
		if (!ChkUtil.isEmpty(sql)) {
			sql = sql.substring(0, sql.length() - 1);
		}
		return sql;
	}
	/**
	 * 根据传入的含","的字符串ids 如8a8ac49f5ad9d83e015ad9f98c0b0003,8a8ac49f5ad9fbaf015ada001cb90001
	 * 及查询字段条件返回带where或带and 的sql条件语句
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param ids  如8a8ac49f5ad9d83e015ad9f98c0b0003,8a8ac49f5ad9fbaf015ada001cb90001
	 * @param fieldName 如查询字段t.name
	 * @return
	 */
	public  CommonMybaitsDataMapExt getSplitInSqlByMapData(String ids,String fieldName,String tempTableName) {
		if(ChkUtil.isEmpty(fieldName)||ChkUtil.isEmpty(ids)){
			return null;
		}
		return  getSplitInSqlByMapData(ids.split(","), fieldName,tempTableName);
	}
	/**
	 * 根据传入的字符串ids数组 如8a8ac49f5ad9d83e015ad9f98c0b0003,8a8ac49f5ad9fbaf015ada001cb90001
	 * 及查询字段条件返回带where或带and 的sql条件语句
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param ids  如8a8ac49f5ad9d83e015ad9f98c0b0003,8a8ac49f5ad9fbaf015ada001cb90001
	 * @param fieldName 如查询字段t.name
	 * @return
	 */
	public  CommonMybaitsDataMapExt getSplitInSqlByMapData(String[] ids,String fieldName,String tempTableName) {
		String inSql="";
		if(ChkUtil.isEmpty(fieldName)||ids==null||ids.length==0){
			return null;
		}
		Set<String> setData=new HashSet<>(Arrays.asList(ids));
		Map  pojoMap=new HashMap();
		int i = 0;  
		for(String id:setData){
			pojoMap.put(id, id);
			if(i++ != 0)   inSql+=",";
			inSql+="#{"+CommonMybaitsDataMapExt.POJO_PREFIX+id+"}";
		}
		String inSqlByWhere=inSql.equals("")?"":" where "+fieldName+" in("+inSql+") ";
		String inSqlByAnd=inSql.equals("")?"":" and  "+fieldName+" in("+inSql+") ";
		if(setData.size()>=1000){
			tempTableName=getUniqueTempTableName(tempTableName);
			this.tempTableName=tempTableName;
			// 定义模板变量
			Map<String, Object> model = Maps.newHashMap();
			List<EntityData> entityData=new ArrayList(){{
				add(new EntityData());
			}};
			model.put("entityData", entityData);
			model.put("tableName", tempTableName);
			model.put("ids", new ArrayList<>(setData));
			String executeSql=FreeMarkers.getFtlData(model, "createTable.ftl");
			mBaseDao.executeSql(executeSql, null);
			inSqlByWhere=inSql.equals("")?"":" ,"+tempTableName+" where "+fieldName+"="+tempTableName+".id ";
			inSqlByAnd="";
		}
		return new CommonMybaitsDataMapExt(inSqlByWhere, inSqlByAnd, pojoMap);
	}
	/**
	 * 根据传入的字符串ids集合对象 如Set,List
	 * 及查询字段条件返回带where或带and 的sql条件语句
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param ids  如8a8ac49f5ad9d83e015ad9f98c0b0003,8a8ac49f5ad9fbaf015ada001cb90001
	 * @param fieldName 如查询字段t.name
	 * @return
	 */
	public  CommonMybaitsDataMapExt getSplitInSqlByMapData(Collection<? extends String>  ids,String fieldName,String tempTableName) {
		String inSql="";
		if(ChkUtil.isEmpty(fieldName)||ids==null||ids.size()==0){
			return null;
		}
		Set<String> setData=new HashSet<>(ids);
		Map  pojoMap=new HashMap();
		int i = 0;  
		for(String id:setData){
			pojoMap.put(id, id);
			if(i++ != 0)   inSql+=",";
			inSql+="#{"+CommonMybaitsDataMapExt.POJO_PREFIX+id+"}";
		}
		String inSqlByWhere=inSql.equals("")?"":" where "+fieldName+" in("+inSql+") ";
		String inSqlByAnd=inSql.equals("")?"":" and  "+fieldName+" in("+inSql+") ";
		if(setData.size()>=1000&&!ChkUtil.isEmpty(tempTableName)){
			tempTableName=getUniqueTempTableName(tempTableName);
			this.tempTableName=tempTableName;
			// 定义模板变量
			Map<String, Object> model = Maps.newHashMap();
			List<EntityData> entityData=new ArrayList(){{
				add(new EntityData());
			}};
			model.put("entityData", entityData);
			model.put("tableName", tempTableName);
			model.put("ids", new ArrayList<>(setData));
			String executeSql=FreeMarkers.getFtlData(model, "createTable.ftl");
			mBaseDao.executeSql(executeSql, null);
			inSqlByWhere=inSql.equals("")?"":" ,"+tempTableName+" where "+fieldName+"="+tempTableName+".id ";
			inSqlByAnd="";
		}
		return new CommonMybaitsDataMapExt(inSqlByWhere, inSqlByAnd, pojoMap);
	}
	
	/**
	 * @Description: TODO(这里用一句话描述这个方法的作用) 
	 * @param tempTableName
	 * @return
	 */
	public  String  getUniqueTempTableName(String tempTableName){
		String pre=isGlobaltempTable?"##temp_":"#temp_";
		String suf=""+new Date().getTime();
		tempTableName=tempTableName==null?pre+suf:pre+tempTableName+suf;
		return tempTableName;
	}
	
	@ModelAttribute
	public void initUserRequest(HttpServletRequest request) throws IOException{
		String userAgent=request.getHeader("user-agent");
		userAgent=userAgent.toUpperCase();
		if(!propertySourceConfig.getIsExecuteHisHttp().equals("true")) this.isHisErr=true;
		if(userAgent.contains("ANDROID")){
			this.userAgent="ANDROID";
		}else if(userAgent.contains("IPHONE")){
			this.userAgent="IPHONE";
		}else if(userAgent.contains("CHROME")){
			this.userAgent="CHROME";
		}else if(userAgent.contains("GECKO")){
			this.userAgent="GECKO";
		}
		
	}
	/**
	 * 查询三方接口动态配置信息
	 * @param id 为空查询所有
	 * @return
	 * @throws IOException
	 */
	public List<TxbyBDApiConfig> getTxbyBDApiConfigInfo(String fullClassName) throws IOException{
		List<TxbyBDApiConfig> bdInfoList=null;
		fullClassName=fullClassNamePre+fullClassName;
		Map param =new HashMap();
		String searchSql="";
		if(!ChkUtil.isEmpty(fullClassName)){
			searchSql+=" and typeFlag=#{pojo.typeFlag}";
			param.put("typeFlag", "his"+fullClassName);
		}
		TxbyBDApiConfig bdAC=null;
		bdInfoList=this.mBaseDao.findAll("select * from "+this.mBaseDao.tableName(TxbyBDApiConfig.class)+" where 1=1 "+searchSql, TxbyBDApiConfig.class, param);
		 
		return bdInfoList;
	}
	/**
	 * http请求返回json
	 * @param httpUrl
	 * @param httpType
	 * @param maps
	 * @return
	 * @throws IOException
	 */
	public String getHttpResponseContent(String httpUrl,String httpType, Map<String, String> maps) throws IOException{
	    String responseContent=HttpToolUtil.getInstance().sendHttpCustom(httpUrl, httpType, maps, false, null);
		return responseContent;
	}
	/**
	 * 根据his api配置typeFlage 参数查询
	 * @param fullClassName
	 * @return
	 * @throws IOException
	 */
	public boolean isHisErr( String fullClassName) throws IOException{
		boolean flag = false;
		fullClassName=fullClassNamePre+fullClassName;
		String sql="select * from "+this.mBaseDao.tableName(TxbyBDApiMonition.class)+" where typeFlag='"+fullClassName+"'";
		TxbyBDApiMonition bda=(TxbyBDApiMonition) this.mBaseDao.findBySqlUniqueObject(sql, TxbyBDApiMonition.class, new HashMap());
		if(!ChkUtil.isEmptyAllObject(bda)){
			flag=bda.getIsErr()==1?true:false;
		}else{
			this.isHisErr=false;
		}
		return flag;
	}
	/**
	 * 获取最新产品设备初始化唯一信息
	 * @param deviceSN
	 * @return
	 * @throws IOException
	 */
	public ProductDeviceInit getProductDeviceInit(String deviceSN){
		if(apiUserId.startsWith("demo:")){
			deviceSN=this.demoDeviceSN;
		}
		String sql = "SELECT * FROM "+this.mBaseDao.tableName(ProductDeviceInit.class)+" WHERE 1=1   ";
		Map params=new HashMap();
		ProductDeviceInit pdi=null;
		if(!ChkUtil.isEmptyAllObject(deviceSN)) {
			params.put("deviceSN", deviceSN);
			sql+=" and deviceSN =#{pojo.deviceSN} ";
			sql+="  order by updateTime desc LIMIT 1";
		   pdi=(ProductDeviceInit) this.mBaseDao.findBySqlUniqueObject(sql, ProductDeviceInit.class, params);
			
		}
		return pdi;
	}
	/**
	 * 获取最新患者详细唯一信息
	 * @param deviceSN
	 * @return
	 * @throws IOException
	 */
	public SickDetailInfo getSickDetailInfo(String deviceSN) throws IOException{
		if(apiUserId.startsWith("demo:")){
			deviceSN=demoDeviceSN;	
		}
		SickDetailInfo sdi=null;
		ProductDeviceInit pdi=getProductDeviceInit(deviceSN);
		String sql="";
		if(pdi!=null&&!ChkUtil.isEmpty(pdi.getDeptId())&&!ChkUtil.isEmpty(pdi.getSickAreaNO())&&!ChkUtil.isEmpty(pdi.getBedNO())){
			sql="SELECT * FROM "+this.mBaseDao.tableName(SickDetailInfo.class)+" WHERE 1=1 and outHosTime is null ";
			if(!ChkUtil.isEmpty(pdi.getDeptId())){
				sql+=" and deptId="+pdi.getDeptId()+"";
			}
			if(!ChkUtil.isEmpty(pdi.getSickAreaNO())){
				sql+=" and sickAreaNO="+pdi.getSickAreaNO()+"";
			}
			if(!ChkUtil.isEmpty(pdi.getBedNO())){
				sql+=" and bedNO='"+pdi.getBedNO()+"'";
			}
			sql+=" order by updateTime desc LIMIT 1";
			sdi=(SickDetailInfo) this.mBaseDao.findBySqlUniqueObject(sql, SickDetailInfo.class, null);
	/*	 if(!ChkUtil.isEmpty(sdi)&&!ChkUtil.isEmpty(sdi.getICNO())){
			return  sdi;
		 } */
		} 
		return sdi;
	}
	
	
	/**
	 * 根据卡号获取医护人员开卡，帐号表信息
	 * @param cardNo
	 * @return
	 * @throws IOException
	 */
	public DctNrsCardCnf getDctNrsCardCnfInfo(String cardNO) throws IOException{
		DctNrsCardCnf dcc=null;
		if(ChkUtil.isEmpty(cardNO)) {
			return null;
		}
		String sql="SELECT * FROM "+this.mBaseDao.tableName(DctNrsCardCnf.class)+" WHERE 1=1 and cardNO=#{pojo.cardNO}";
		Map m = new HashMap(2);
		m.put("cardNO", cardNO);
		dcc=(DctNrsCardCnf) this.mBaseDao.findBySqlUniqueObject(sql, DctNrsCardCnf.class, m);
		return dcc;
	}
	/**
	 * 查询是否为访客
	* @Title: getVisitorUserCheck 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param apiUserId
	* @param @return    设定文件 
	* @return VisitorUser    返回类型 
	* @throws
	 */
	public VisitorUser getVisitorUserCheck(String apiUserId){
		VisitorUser vu=null;
		String [] vstData=apiUserId.split("vst:");
		if(apiUserId.startsWith("vst:")&&vstData.length>=2){
			//视为访客
			vu=(VisitorUser) this.mBaseDao.findBySqlUniqueObject("select * from "+this.mBaseDao.tableName(VisitorUser.class)+" where id_="+vstData[1]+" ", VisitorUser.class, null);
			if(ChkUtil.isEmpty(vu)){
				vu=new VisitorUser();
			}
		}
		return vu;
	}
/**
 * 根据总类别查询表名
* @Title: getGoodsTableName 
* @Description: TODO(这里用一句话描述这个方法的作用) 
* @param @param gTypeId
* @param @return    设定文件 
* @return String    返回类型 
* @throws
 */
	public String  getGoodsTableName(Integer gTypeId){
		String tableName=" t_txby_sp_baseGoods ";
/*		1	1	2017-10-26 08:30:53	2017-10-26 08:30:53	1	1	0	01	护理服务
		2	2	2017-10-26 08:30:53	2017-10-26 08:30:53	1	1	0	02	普通服务
		3	3	2017-10-26 08:30:53	2017-10-26 08:30:53	1	1	0	03	床旁点餐
		4	4	2017-10-26 08:30:53	2017-10-26 08:30:53	1	1	0	04	商品*/
		switch (gTypeId) {
		case 1:
			tableName="t_txby_sp_nrsGoods";
			break;
	
		case 2:
			tableName="t_txby_sp_serviceGoods";
			break;
			
		case 3:
			tableName="t_txby_sp_orderMealGoods";
			break;
			
		case 4:
			tableName="t_txby_sp_baseGoods";
			break;
	 
		}
		return tableName;
	}
	
	/**
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * 获取患者平板默认的医院关联的信息
	* @Title: getProductDevicedeptRegionAndSickInfoAddressInfo 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param deviceSN
	* @param @return    设定文件 
	* @return Map    返回类型 
	* @throws
	 */
	public Map getProductDeviceDeptRegionAndSickInfoAddressInfo(String deviceSN) throws Exception{
		  String sql=" SELECT t.deviceSN,t.deptId,t2.name deptName,t.sickAreaNO,t5.name sickAreaName,t.bedNO,t4.parentCode parentCode,t4.level regionLevel,t4.regionName,t3.address FROM  t_txby_productDeviceInit  t INNER JOIN sys_dept  t2 on t.deptId=t2.dept_id  INNER JOIN  sys_dept  t5 on t5.dept_id=t.sickAreaNO  LEFT   JOIN t_txby_sysDeptRegionRelation t3 on t2.dept_id=t3.deptId LEFT JOIN sys_chinaRegion t4 on t4.id_=t3.regionId where t.deviceSN='"+deviceSN+"'";
		  Map  data=new HashMap();
		  data.put("deptRegionAndSickInfoAddress", null);
		  data.put("fullAddress", null);
		  
		  Map deptRegionAndSickInfoAddress=new HashMap();
		 Map sqlMap=(Map) this.mBaseDao.findBySqlUniqueObject(sql, null, null);
		 if(null!=sqlMap&&sqlMap.size()>0){
			 if(sqlMap.get("parentCode")!=null){
				 Long parentCode=new Long(sqlMap.get("parentCode").toString());
				 String address=sqlMap.get("address").toString();
				 Integer regionLevel=new Integer(sqlMap.get("regionLevel").toString());
				 String regionName=sqlMap.get("regionName").toString();
				 String deptName=sqlMap.get("deptName").toString();
				 String sickAreaName=sqlMap.get("sickAreaName").toString();
				 String bedNO=sqlMap.get("bedNO").toString();
				 String fullAddress=getDeviceHosInfoByRegionList(parentCode);
				 fullAddress+="-"+regionName+"-"+address+deptName+sickAreaName+bedNO+"床";
				 data.put("fullAddress", fullAddress);
				 deptRegionAndSickInfoAddress.put("fullAddress", fullAddress);
				 
				 BeanUtils.copyProperties(deptRegionAndSickInfoAddress, sqlMap);
				 data.put("deptRegionAndSickInfoAddress", deptRegionAndSickInfoAddress);
			 }else{
				 BeanUtils.copyProperties(deptRegionAndSickInfoAddress, sqlMap);
				 data.put("deptRegionAndSickInfoAddress", deptRegionAndSickInfoAddress);
			 }
			 
		 }else{
			 
			 return data;
		 }
		 
		 return data;
		 
	}
	/**
	 * 获取区域tree相关数据
	* @Title: getTreeDataListAndJsonTree 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @return
	* @param @throws Exception    设定文件 
	* @return Map    返回类型 
	* @throws
	 */
	public Map   getTreeDataListAndJsonTree()   {
		Map data=new HashMap();
		data.put("list", new ArrayList<>());
		data.put("json", "");
		String sql="SELECT  (SELECT count(*) FROM sys_chinaRegion t WHERE t.level<>0 and t.level <=3) count,t.* FROM sys_chinaRegion t WHERE t.level<>0 and t.level <=3 ORDER BY LEVEL  ";
		List<HashMap> dataList=mBaseDao.findBySql(sql, null, null);
		System.out.println(dataList.size());
		List<HashMap>  tempList=new ArrayList<>();
		List<TreeNode> treeNodes=new ArrayList<>();
		for(HashMap m:dataList){
			HashMap tm=new HashMap();
			tm.put("id", m.get("code"));
			tm.put("pId", m.get("parentCode"));
			tm.put("name", m.get("regionName"));
			TreeNode tn=new TreeNode(m.get("code").toString(), m.get("parentCode").toString(), m.get("regionName").toString(),Integer.parseInt(m.get("level").toString()),Long.parseLong(m.get("id_").toString()));
			tempList.add(tm);
			treeNodes.add(tn);
		}
		String json = new TreeUtil().buildTree(treeNodes);
//		System.out.println(json);
		data.put("list", tempList);
		data.put("json", json);
	 
		return data; 
		
	}
	@ModelAttribute
	public void initData(){
		if(springEhcacheUtil.get(apiTokenCachName, cacheTreeData)==null){
			Map data=getTreeDataListAndJsonTree();
			this.springEhcacheUtil.put(apiTokenCachName, cacheTreeData, data);
		}
		
	}
	/**
	 * 检查是否患者，访客
	* @Title: checkSickOrVisitorUser 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param deviceSN
	* @param @return
	* @param @throws IOException    设定文件 
	* @return CommonApiModelMapExt    返回类型 
	* @throws
	 */
	public CommonApiModelMapExt checkSickOrVisitorUser(String deviceSN) throws IOException{
		CommonApiModelMapExt mm= new CommonApiModelMapExt(0,"正常", null, null, null) ;
		  vu=getVisitorUserCheck(apiUserId);
	 
		if(!ChkUtil.isEmpty(vu)&&vu.getId_()==null){
			mm.put(CommonApiModelMapExt.ERRCODE, 1);
			mm.put(CommonApiModelMapExt.ERRMSG, "访客用户不存在");
			
		}else{
			 if(!ChkUtil.isEmpty(deviceSN)){
				 sdi=getSickDetailInfo(deviceSN);
				 if (ChkUtil.isEmpty(sdi)) {
					 mm.put(CommonApiModelMapExt.ERRCODE, 4202);
					 mm.put(CommonApiModelMapExt.ERRMSG, "患者不存在或患者已出院");
				 }
				 
			 }else{
				 mm.put(CommonApiModelMapExt.ERRCODE, 1);
				 mm.put(CommonApiModelMapExt.ERRMSG, "设备sn为空");
				 
			 }

		}
		return mm;
		
	}
	
	
	List<String> fullRegion=new ArrayList<>();
	/**
	 * 递归查询医院详细区域信息
	* @Title: getDeviceHosInfoByRegionList 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param parentCode
	* @param @param level
	* @param @return    设定文件 
	* @return List<String>    返回类型 
	* @throws
	 */
	public List<String> getDeviceHosInfoByRegionList(long parentCode,Integer level){
		if (level>1) {
			String sql="SELECT * FROM  sys_chinaRegion t WHERE t.code ="+parentCode+"";
			 Map temp=(Map) this.mBaseDao.findBySqlUniqueObject(sql, null, null);
			 if(temp!=null){
				 fullRegion.add(temp.get("regionName").toString());
				 getDeviceHosInfoByRegionList(new Long(temp.get("parentCode").toString()), new Integer(temp.get("level").toString()));
			 }
			
		}
		return fullRegion;
	}
	/**
	 * 递归查询医院详细区域信息
	* @Title: getDeviceHosInfoByRegionList 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param parentCode
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public String getDeviceHosInfoByRegionList(long parentCode){
		if(parentCode!=100000000000l){
			String sql="SELECT * FROM  sys_chinaRegion t WHERE t.code ="+parentCode+"";
			Map temp=(Map) this.mBaseDao.findBySqlUniqueObject(sql, null, null);
			if(temp!=null){
				Long code=new Long(temp.get("parentCode").toString());
				String regionName=temp.get("regionName").toString();
				if(!fullRegion.contains(regionName)){
					fullRegion.add(regionName);
				}
				getDeviceHosInfoByRegionList(new Long(code));
			}
			
		}
		return getDeviceHosInfoByRegionListReveseString(fullRegion);
	}
	/**
	 * 反转List 集合数据
	* @Title: getDeviceHosInfoByRegionListReveseString 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param fullRegion
	* @param @return    设定文件 
	* @return String    返回类型 
	* @throws
	 */
	public  static String  getDeviceHosInfoByRegionListReveseString(List<String> fullRegion){
		String regionName="";
		int size=fullRegion!=null?fullRegion.size():0;
		for(int i=size-1;i>=0;i--){
			if(i!=0){
				regionName+=fullRegion.get(i)+"-";
			}else{
				regionName+=fullRegion.get(i);
			}
		}
		return regionName;
	}
	

	
	
	
	
}
